<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>画笔矩形框绘制工具</title>
    <style>
        canvas {
            border: 1px solid black;
        }
        #toolbar {
            margin-bottom: 10px;
        }
    </style>
</head>
<body>
    <div id="toolbar">
        <button onclick="setMode('draw')">Draw</button>
        <button onclick="setMode('rect')">Rectangle</button>
        <button onclick="undo()">Undo</button>
        <button onclick="redo()">Redo</button>
        <button onclick="toggleDisable()">Toggle Disable</button>
        <input type="color" id="colorPicker" value="#000000">
        <input type="color" id="fillColorPicker" value="#ffffff">
        <input type="range" id="brushSize" min="1" max="10" value="5">
        <input type="range" id="alpha" min="0" max="1" step="0.1" value="1">
    </div>
    <canvas id="canvas" width="800" height="600"></canvas>

    <script>
        const canvas = document.getElementById('canvas');
        const ctx = canvas.getContext('2d');
        let drawing = false;
        let mode = 'draw';
        let disable = false;
        let startX, startY;
        let history = [];
        let redoStack = [];
        let currentRect = null;

        ctx.lineCap = 'round';
        ctx.lineJoin = 'round';

        function setMode(newMode) {
            mode = newMode;
        }

        function toggleDisable() {
            disable = !disable;
        }

        function undo() {
            if (history.length > 0) {
                redoStack.push(history.pop());
                redraw();
            }
        }

        function redo() {
            if (redoStack.length > 0) {
                history.push(redoStack.pop());
                redraw();
            }
        }

        function redraw() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            history.forEach(step => {
                ctx.strokeStyle = step.color;
                ctx.fillStyle = step.fillColor;
                ctx.lineWidth = step.size;
                ctx.beginPath();
                if (step.type === 'draw') {
                    ctx.moveTo(step.points[0].x, step.points[0].y);
                    for (let i = 1; i < step.points.length; i++) {
                        ctx.lineTo(step.points[i].x, step.points[i].y);
                    }
                } else if (step.type === 'rect') {
                    const rect = step.rect;
                    ctx.rect(rect.x, rect.y, rect.width, rect.height);
                    ctx.fill();
                }
                ctx.stroke();
            });
        }

        function hexToRgba(hex, alpha) {
            let r = parseInt(hex.slice(1, 3), 16);
            let g = parseInt(hex.slice(3, 5), 16);
            let b = parseInt(hex.slice(5, 7), 16);
            return `rgba(${r}, ${g}, ${b}, ${alpha})`;
        }

        canvas.addEventListener('mousedown', e => {
            if (disable) return;
            drawing = true;
            startX = e.offsetX;
            startY = e.offsetY;
            const alpha = document.getElementById('alpha').value;
            ctx.strokeStyle = hexToRgba(document.getElementById('colorPicker').value, alpha);
            ctx.fillStyle = hexToRgba(document.getElementById('fillColorPicker').value, alpha);
            ctx.lineWidth = document.getElementById('brushSize').value;
            if (mode === 'draw') {
                ctx.beginPath();
                ctx.moveTo(startX, startY);
                history.push({type: 'draw', color: ctx.strokeStyle, size: ctx.lineWidth, points: [{x: startX, y: startY}]});
            } else if (mode === 'rect') {
                currentRect = {x: startX, y: startY, width: 0, height: 0};
            }
        });

        canvas.addEventListener('mousemove', e => {
            if (disable || !drawing) return;
            const x = e.offsetX;
            const y = e.offsetY;
            if (mode === 'draw') {
                ctx.lineTo(x, y);
                ctx.stroke();
                history[history.length - 1].points.push({x, y});
            } else if (mode === 'rect') {
                const rect = {
                    x: Math.min(startX, x),
                    y: Math.min(startY, y),
                    width: Math.abs(x - startX),
                    height: Math.abs(y - startY)
                };
                currentRect = rect;
                redraw();
                ctx.strokeStyle = hexToRgba(document.getElementById('colorPicker').value, document.getElementById('alpha').value);
                ctx.fillStyle = hexToRgba(document.getElementById('fillColorPicker').value, document.getElementById('alpha').value);
                ctx.lineWidth = document.getElementById('brushSize').value;
                ctx.beginPath();
                ctx.rect(rect.x, rect.y, rect.width, rect.height);
                ctx.fill();
                ctx.stroke();
            }
        });

        canvas.addEventListener('mouseup', e => {
            if (disable) return;
            drawing = false;
            if (mode === 'rect') {
                const rect = currentRect;
                history.push({type: 'rect', color: ctx.strokeStyle, fillColor: ctx.fillStyle, size: ctx.lineWidth, rect});
                currentRect = null;
                redoStack = [];
            }
        });

        canvas.addEventListener('mouseout', e => {
            if (disable) return;
            drawing = false;
            if (mode === 'rect') {
                currentRect = null;
                redraw();
            }
        });
    </script>
</body>
</html>
